package com.cloudptt.api.product.func.call.group.fsm.floor;

import android.content.Context;

import com.cloudptt.api.comm.CauseCont;
import com.cloudptt.api.comm.CommDlg;
import com.cloudptt.api.models.call.RtcpMsg;
import com.cloudptt.api.product.func.call.CallAttr;
import com.cloudptt.api.product.func.addr.IAddrOp;
import com.cloudptt.api.product.func.call.CallConst;
import com.cloudptt.api.product.func.call.CallTimer;
import com.cloudptt.api.product.func.call.group.GroupCallSpeakListener;
import com.cloudptt.api.product.log.Log;
import com.cloudptt.api.product.operator.CallOperator;
import com.cloudptt.api.product.res.Resource;
import com.mcptt.db.model.AddrInfo;

public class FloorAgent implements ISubState
{
	public final static String Log_Key = "FloorAgent";
	private ISubState currentState = null;
	private GroupCallSpeakListener listener = null;
	private Context ctx = null;
	private String callIdStr = CallAttr.DEF_CALL_ID_STR;
	private CallOperator operator = null;
	private IAddrOp addOp = null;
//	private IRollback rollback = null;
	private CallTimer callTimer = null;
	private RtcpMsg lastFloorTakenRtcpMsg = null;

	private AddrInfo floorUserInfo = null;
	private String callKey = null;

	public FloorAgent(Context ctx,String callIdStr,String callKey,CallOperator operator,IAddrOp addOp,CallTimer callTimer)
	{
		Log.d(FloorAgent.Log_Key, "FloorAgent");
		this.ctx = ctx;
		this.callIdStr = callIdStr;
		this.callKey = callKey;
		this.callTimer = callTimer;
		this.operator = operator;
		this.addOp = addOp;
		this.currentState = new FloorNoPermissionState(this);
	}
	
	public void setListener(GroupCallSpeakListener listener)
	{
		this.listener = listener;
	}
	public void updateCallIdStr(String callIdStr)
	{
		this.callIdStr = this.callIdStr;
	}

	public void goToState(int nextState,RtcpMsg msg)
	{
		ISubState videoState = null;
		Log.d(FloorAgent.Log_Key, "goToState:["+ CallConst.stateTag(this.currentState.getState()) +
				" to "+ CallConst.stateTag(nextState) + "]");

			switch (nextState) {
			case CallConst.FloorState_NoPermission:
				videoState = new FloorNoPermissionState(this);
				break;
			case CallConst.FloorState_PendingRequset:
				videoState = new FloorPendingRequestState(ctx,this);
				break;
			case CallConst.FloorState_Permission:
				videoState = new FloorPermissionState(this);
				break;
			case CallConst.FloorState_PendingRelease:
				videoState = new FloorPendingReleaseState(ctx,this);
				break;
			default:
				Log.e(FloorAgent.Log_Key, "Illegal state="+ nextState);
				return;//!!!
			}
			this.setCurrentState(videoState);
			if(nextState == CallConst.FloorState_NoPermission
					&& msg != null)
			{
				this.receiveRtcpMsg(msg);
			}
		if(nextState == CallConst.FloorState_NoPermission
				&&lastFloorTakenRtcpMsg != null)
		{
			this.receiveRtcpMsg(lastFloorTakenRtcpMsg);
		}
	}

	private void setCurrentState(ISubState currentState)
	{
		this.currentState.destory();
		this.currentState = currentState;
		int state = currentState.getState();
		Log.d( FloorAgent.Log_Key,
				CallConst.stateTag(this.currentState.getState()) + " setCurrentState = " + CallConst.stateTag(state));
		if(listener != null)
		{
			listener.updateSpeakState(callKey,state);
		}
	}
	
	public void updateSpeakPermissionNum(String num) 
	{
		Log.d( FloorAgent.Log_Key,
				CallConst.stateTag(this.currentState.getState()) + " updateSpeakPermissionNum = " + num);

		if(listener != null
				&& num != null)
		{
			int state = currentState.getState();
			if(num.equals(""))
			{
				listener.updateSpeakPermissionInfo(callKey,state,null);
				floorUserInfo = null;
			}
			else
			{
				floorUserInfo = addOp.getUserInfoByNum(num);
				listener.updateSpeakPermissionInfo(callKey,state,floorUserInfo);
				if(operator != null) {
					operator.requestWakeLock(ctx, 10);
				}
			}
		}
		
	}
	
	public int getCurrentState()
	{
		return this.currentState.getState();
	}

	public int doUserAction(int action)
	{
		Log.d( FloorAgent.Log_Key,
				CallConst.stateTag(this.currentState.getState()) + " doUserAction = " + CallConst.userActionTag( action ));
		return this.currentState.doUserAction(action);
	}

	public void receiveRtcpMsg(RtcpMsg msg)
	{
		String title = msg.getTitle();
		Log.d(FloorAgent.Log_Key, "floorAgent receiveRtcpMsg title = " + title);
		if(title.equals(RtcpMsg.Title_FLOOR_TAKEN))
		{
			this.lastFloorTakenRtcpMsg = msg;
		}
		else if(title.equals(RtcpMsg.Title_FLOOR_IDLE))
		{
			this.lastFloorTakenRtcpMsg = null;
		}
		Log.d(FloorAgent.Log_Key, CallConst.stateTag(this.currentState.getState()) + " receiveRtcpMsg msg = " + msg);
		this.currentState.receiveRtcpMsg(msg);
	}
	
	public void showTalkEndToast()
	{
		String errStr = Resource.getString("e_pttfloorrelreq_1");
		CommDlg.showToast(ctx, errStr);
	}
	
	public int getState()
	{
		return this.currentState.getState();
	}
	public CallTimer getCallTimer() {
		return callTimer;
	}

	public void updateTime(CallTimer timer) {
		this.callTimer.updateTime(timer);
	}
	
	
	protected int floorRequest()
	{
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
			CommDlg.showToast(ctx,errStr);
			return CauseCont.OperateCheck_Sys_UserKeyNull;
		}
		int result = operator.sendFloorMsg(callIdStr,CallAttr.RtcpMsg_Request);
		if(result != CauseCont.OperateCheck_Suc) 
		{
			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
			CommDlg.showToast(ctx,errStr);
			return result;
		}
		return CauseCont.OperateCheck_Suc;
	}
	
	protected int floorRelease()
	{
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
			CommDlg.showToast(ctx,errStr);
			return CauseCont.OperateCheck_Sys_UserKeyNull;
		}
		
		int result = operator.sendFloorMsg(callIdStr,CallAttr.RtcpMsg_Release);
		if(result != CauseCont.OperateCheck_Suc) 
		{
			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
			CommDlg.showToast(ctx,errStr);
			return result;
		}
		return CauseCont.OperateCheck_Suc;
	}
	
	public void opAudioMedia(int opType)
	{
		Context ctx = this.getCtx();
		if(null == operator
				|| null == ctx)
		{
			String errStr =  Resource.getString("operator_null");//ctx.getString(R.string.operator_null);
			CommDlg.showToast(ctx,errStr);
			return;
		}
		
		int result = operator.opAudioMedia(callIdStr,opType);
		if(result != CauseCont.OperateCheck_Suc) 
		{
			String errStr = CauseCont.getOperateCheckErrStr(result,ctx);
			CommDlg.showToast(ctx,errStr);
			return;
		}
	}
	
	public AddrInfo getFloorUserInfo() {
		return floorUserInfo;
	}

	@Override
	public void destory() {
		// TODO Auto-generated method stub
		this.currentState.destory();
	}
	
	public Context getCtx() {
		return ctx;
	}

	public CallOperator getOperator() {
		return operator;
	}
	
	public void clearResource()
	{
		currentState.destory();
		currentState = null;
		listener = null;
		ctx = null;
		operator = null;
		callTimer = null;
	}
}
